package com.pureut.equipment.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pureut.equipment.domain.*;
import com.pureut.equipment.domain.dto.EquipmentKnowledgeDto;
import com.pureut.equipment.domain.dto.EquipmentRepairDto;
import com.pureut.equipment.domain.dto.MaintenanceProjectDto;
import com.pureut.equipment.domain.vo.EquipmentRepairVo;
import com.pureut.equipment.domain.vo.ReturnDeviceStatusVo;
import com.pureut.equipment.mapper.EquipmentKnowledgeMapper;
import com.pureut.equipment.mapper.EquipmentRepairMapper;
import com.pureut.equipment.service.IEquipmentKnowledgeService;
import com.pureut.equipment.service.IEquipmentRepairService;
import com.sale.common.core.exception.GlobalException;
import com.sale.common.core.utils.DateUtils;
import com.sale.common.dict.utils.DictUtils;
import com.sale.common.mybatis.core.page.PageQuery;
import com.sale.common.mybatis.core.page.TableDataInfo;
import com.sale.common.satoken.utils.LoginHelper;
import com.sale.storage.api.vo.QuantityDataVo;
import com.sale.storage.api.vo.UpdateInvoicedQuantityVo;
import com.sale.system.api.RemoteCodeService;
import com.sale.system.api.RemoteDeviceService;
import com.sale.system.api.RemoteExamineService;
import com.sale.system.api.domain.SysBalance;
import com.sale.system.api.domain.SysDictData;
import com.sale.system.api.domain.dto.DeviceApiRecordDto;
import com.sale.system.api.domain.vo.ReturnApiDeviceStatusVo;
import com.sale.system.api.domain.vo.SysAuditHistoryVo;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description 设备维修实现类
 * @Param EquipmentRepair
 * @Date 23-04-24f
 * @Author hl
 **/
@Service
public class EquipmentRepairServiceImpl extends ServiceImpl<EquipmentRepairMapper, EquipmentRepair> implements IEquipmentRepairService {

    @Resource
    private EquipmentRepairMapper equipmentRepairMapper;

    @DubboReference
    RemoteCodeService remoteCodeService;

    @Resource
    EquipmentKnowledgeMapper equipmentKnowledgeMapper;

    @Resource
    RemoteExamineService remoteExamineService;

    @Resource
    IEquipmentKnowledgeService equipmentKnowledgeService;

    @DubboReference
    RemoteDeviceService remoteDeviceService;


    /**
     * 查询设备维修列表
     *
     * @param equipmentRepairVo 接受类
     * @return 设备维修列表
     */
    @Override
    public TableDataInfo<EquipmentRepairDto> selectRepairList(EquipmentRepairVo equipmentRepairVo, PageQuery pageQuery) {
        Page<EquipmentRepairDto> equipmentRepairDtos = equipmentRepairMapper.selectRepairList(equipmentRepairVo, pageQuery.build());

        //获取紧急程度字典
        List<SysDictData> urgencyArray = DictUtils.getDictCache("equipment_of_urgency");
        Map<String, String> urgencyMap = urgencyArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        //获取设备类型字典
        List<SysDictData> deviceTypeArray = DictUtils.getDictCache("device_type");
        Map<String, String> deviceTypeMap = deviceTypeArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        //获取故障类别字典
        List<SysDictData> failureArray = DictUtils.getDictCache("equipment_failure_type");
        Map<String, String> failureMap = failureArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        List<EquipmentRepairDto> records = equipmentRepairDtos.getRecords();
        for (EquipmentRepairDto entity : records) {
            //紧急程度
            entity.setRepairUrgentDict(urgencyMap.get(entity.getRepairUrgent()));
            //设备类型
            entity.setDeviceTypeDict(deviceTypeMap.get(entity.getDeviceType()));
            //故障类别
            entity.setRepairFailureTypeDict(failureMap.get(entity.getRepairFailureType()));
        }
        return TableDataInfo.build(equipmentRepairDtos);
    }

    /**
     * 新增设备维修
     *
     * @param equipmentRepair 接受类
     * @return 成功 true 失败 false
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean insertEquipmentRepair(EquipmentRepair equipmentRepair) throws Exception {
        String authorityCoding = remoteCodeService.authorityCoding("device:repair:equipment:list");
        if (authorityCoding == null) {
            throw new GlobalException("该单据未进行配置，无法生成单据编码");
        }
        equipmentRepair.setRepairCode(authorityCoding);
        equipmentRepair.setCreateTime(DateUtils.getTime());
        equipmentRepair.setDeptId(String.valueOf(LoginHelper.getDeptId()));
        equipmentRepair.setRepairState("1");
        equipmentRepair.setRepairWarrantyTime(DateUtils.getTime());
        return save(equipmentRepair);
    }

    /**
     * 修改设备维修
     *
     * @param equipmentRepair 接受类
     * @return 成功 true 失败 false
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateEquipmentRepair(EquipmentRepair equipmentRepair) {
        EquipmentRepair byId = getById(equipmentRepair.getRepairId());
        //如果为不通过
        if(byId.getRepairState().equals("6")){
            //调用审核
            SysAuditHistoryVo sysAuditHistoryVo = new SysAuditHistoryVo();
            String perms = "device:repair:equipment:examine";
            String auditDoc = byId.getRepairCode();
            sysAuditHistoryVo.setAuditDoc(auditDoc);
            sysAuditHistoryVo.setPerms(perms);
            Integer integer = remoteExamineService.editHistory(sysAuditHistoryVo);
            if (integer > 0) {
                //修改审核代办状态为已处理
//                feignService.updateStatus(3,maintenanceWorkOrder.getMaintenanceNumber(),"保养工单");
                equipmentRepair.setRepairState("1");
                updateById(equipmentRepair);
                //清空维修信息

            } else {
                return false;
            }
        }
        return updateById(equipmentRepair);
    }

    /**
     * 查询单个设备维修列表
     *
     * @param repairId id
     * @return 设备维修列表
     */
    @Override
    public EquipmentRepairDto selectRepairById(long repairId) {
        //获取设备类型字典
        List<SysDictData> deviceTypeArray = DictUtils.getDictCache("device_type");
        Map<String, String> deviceTypeMap = deviceTypeArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        EquipmentRepairDto equipmentRepairDto = equipmentRepairMapper.selectRepairById(repairId);
        //根据id获取单个设备信息
        DeviceApiRecordDto deviceById = remoteDeviceService.getDeviceById(equipmentRepairDto.getDeviceId());
        if (deviceById != null) {
            equipmentRepairDto.setDeviceName(deviceById.getDeviceName());
            equipmentRepairDto.setDeviceCode(deviceById.getDeviceCode());
            equipmentRepairDto.setDeviceType(deviceById.getDeviceType());
            equipmentRepairDto.setDeviceTypeDict(deviceTypeMap.get(deviceById.getDeviceType()));
            equipmentRepairDto.setDeviceUnitType(deviceById.getDeviceUnitType());
            equipmentRepairDto.setInstallationLocation(deviceById.getInstallationLocation());
        }
//        String lineCode = equipmentRepairDto.getInstallationLocation();
//        AjaxResult modelingLineInfo = feignService.getModelingLineInfo(lineCode);
//        SysLineDto sysLineDto = JSON.parseObject(JSON.toJSONString(modelingLineInfo.get("data")), SysLineDto.class);
//        equipmentRepairDto.setInstallationLocationName(sysLineDto.getLineName());
        return equipmentRepairDto;
    }

    /**
     * 删除设备维修
     *
     * @param repairId id
     * @return 成功 true 失败 false
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteRepairById(long repairId) {
        return removeById(repairId);
    }

    /**
     * 派工
     *
     * @param equipmentDispatch
     * @return 成功 1 失败 0
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int dispatchEquipmentRepair(EquipmentDispatch equipmentDispatch) {
        equipmentDispatch.setRepairDispatchTime(DateUtils.getTime());
        String code = equipmentDispatch.getDeviceCode();
        DeviceApiRecordDto deviceApiRecordDto = remoteDeviceService.selectEquipmentById(code);
        ReturnApiDeviceStatusVo returnApiDeviceStatusVo = new ReturnApiDeviceStatusVo();
        returnApiDeviceStatusVo.setDeviceIds(String.valueOf(deviceApiRecordDto.getId()));
        returnApiDeviceStatusVo.setStatus(3);
        remoteDeviceService.returnDeviceStatus(returnApiDeviceStatusVo);
        return equipmentRepairMapper.dispatchEquipmentRepair(equipmentDispatch);
    }

    /**
     * 执行维修
     *
     * @param equipmentMaintenance
     * @return 成功 1 失败 0
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int maintenanceEquipmentRepair(EquipmentMaintenance equipmentMaintenance) {
        long endTime = equipmentMaintenance.getRepairEndTime().getTime();
        long startTime = equipmentMaintenance.getRepairStartTime().getTime();
        long diff = (endTime - startTime) / 1000 / 60;
        BigDecimal bd = new BigDecimal(diff);
        BigDecimal bd2 = new BigDecimal(60);
        bd = bd.divide(bd2, RoundingMode.CEILING);
        equipmentMaintenance.setRepairTime(bd.doubleValue());
        return equipmentRepairMapper.maintenanceEquipmentRepair(equipmentMaintenance);
    }

    /**
     * 提交审核
     *
     * @param repairId id
     * @return 成功 1 失败 0
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int submitEquipmentRepair(long repairId) {
        EquipmentState equipmentState = new EquipmentState();
        equipmentState.setRepairState(4);
        equipmentState.setRepairId(repairId);
        return equipmentRepairMapper.submitEquipmentRepair(equipmentState);
    }

    /**
     * 审核单据
     *
     * @param equipmentState id
     * @return 成功 1 失败 0
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int auditEquipmentRepair(EquipmentState equipmentState) throws Exception {
        Long userId = LoginHelper.getUserId();
        SysAuditHistoryVo sysAuditHistoryVo = new SysAuditHistoryVo();
        sysAuditHistoryVo.setPerms("device:repair:equipment:examine");
        sysAuditHistoryVo.setAuditRemarks(equipmentState.getRepairOpinion());
        sysAuditHistoryVo.setAuditDoc(equipmentState.getRepairCode());
        sysAuditHistoryVo.setUserId(userId);
        sysAuditHistoryVo.setAuditState(equipmentState.getRepairWhether());
        sysAuditHistoryVo.setModuleType(7);

        Integer sequence = remoteExamineService.getSequence(sysAuditHistoryVo);
        if (sequence == null) {
            throw new GlobalException("未对该审核进行配置");
        }
        switch (sequence) {
            case 1:
                if (equipmentState.getRepairWhether() == 2) {
                    equipmentState.setRepairState(6);
                } else {
                    equipmentState.setRepairState(7);
                }
                break;
            case 2:
                equipmentState.setRepairState(5);
                break;
            case 3:
                throw new GlobalException("该用户无权限进行审核");
            case 4:
                throw new GlobalException("该用户已审核过");
        }
        //1 审核完成、2 还存在下个审核、3 没权限 、4 该人员已审核
        return equipmentRepairMapper.submitEquipmentRepair(equipmentState);
    }


    /**
     * 添加知识库
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addKnowLedge(Long id) throws Exception {
        //获取设备维修信息
        EquipmentRepair equipmentRepair = getById(id);
        //只能对已完成的单据进行添加知识库功能
        if (!"7".equals(equipmentRepair.getRepairState())) {
            throw new GlobalException("只能对已完成的单据进行添加知识库功能");
        }
        //添加了的维修单不可重复添加知识库，若重复操作则提示“此单据已记录在知识库中"
        EquipmentKnowledgeDto equipmentKnowledgeDto = equipmentKnowledgeMapper.selectKnowledgeByCode(equipmentRepair.getRepairCode());
        if (equipmentKnowledgeDto != null) {
            throw new GlobalException("此单据已记录在知识库中");
        }
        //生成一条数据。同步数据：设备信息、故障类型、故障描述、故障图片、故障分析、处理过程、备件信息、知识库名称默认为"设备名称"+“知识库”）
        EquipmentKnowledge equipmentKnowledge = new EquipmentKnowledge();
        //获取设备信息
        long l = Long.parseLong(equipmentRepair.getDeviceId());
        DeviceApiRecordDto deviceById = remoteDeviceService.getDeviceById(l);
        String authorityCoding = remoteCodeService.authorityCoding("device:repair:knowledge:list");
        equipmentKnowledge.setKnowledgeCode(authorityCoding)
            .setDeviceId(l)
            .setKnowledgeFailureType(Integer.parseInt(equipmentRepair.getRepairFailureType()))
            .setKnowledgeFailureDescription(equipmentRepair.getRepairFailureDescription())
            .setKnowledgeFailurePicture(equipmentRepair.getRepairFailurePicture())
            .setKnowledgeFailureAnalysis(equipmentRepair.getRepairAnalysis())
            .setKnowledgeFailureProcess(equipmentRepair.getRepairDealWith())
            .setCreateTime(DateUtils.getTime())
            .setCreateBy(LoginHelper.getUsername())
            .setDeptId(String.valueOf(LoginHelper.getDeptId()))
            .setRepairCode(equipmentRepair.getRepairCode());
        if (deviceById != null) {
            equipmentKnowledge.setKnowledgeName(deviceById.getDeviceName() + "知识库");
        }

        return equipmentKnowledgeMapper.saveData(equipmentKnowledge) > 0;
    }
}
